`include "define.v"
/*
    流水线寄存器内部信号命名规则：流水线寄存器名_信号名_输入/输出
*/
module IFS_IDF
(
    // Global signal
    input   wire                clk,
    input   wire                rstn,
    // Pipline control signal
    input   wire                flush,
    input   wire                stall, 
    // Pineline register input
    input   wire    [31:00]     IFS_IDF_INSTR_i,                          
    input   wire    [63:00]     IFS_IDF_PC_i,               
    input   wire                IFS_IDF_BUBBLE_FLAG_i,          // 标志本级流水线寄存器中的指令instr是否是bubble（气泡）指令，高有效
    input   wire    [63:00]     IFS_IDF_BRANCH_RESERVE_ADDR_i,        /* 
                                                                        若IFS_IDF_INSTR_i为branch指令，且进行了分支预测的跳转�
                                                                        则该端口输入的内容则为本条指令的PC+4，留作分支预测失败后往回跳转�
                                                                    */ 
    input   wire                IFS_IDF_BRANCH_PREDIC_RES_i,          // 标志本级流水线寄存器中的指令instr是否是进行了分支预测跳转，高有效
    // Pineline register output
    output  reg     [31:00]     IFS_IDF_INSTR_o,
    output  reg     [63:00]     IFS_IDF_PC_o,  
    output  reg                 IFS_IDF_BUBBLE_FLAG_o,
    output  reg     [63:00]     IFS_IDF_BRANCH_RESERVE_ADDR_o,
    output  reg                 IFS_IDF_BRANCH_PREDIC_RES_o   
);
    always @(posedge clk)   begin
        if  (!rstn | flush)   begin
            IFS_IDF_INSTR_o                       <=  `BUBBLE;
            IFS_IDF_PC_o                          <=  64'b0;
            IFS_IDF_BUBBLE_FLAG_o                 <=  1'b1;
            IFS_IDF_BRANCH_RESERVE_ADDR_o         <=  64'b0;
            IFS_IDF_BRANCH_PREDIC_RES_o           <=  1'b0;
        end
        else if ( stall )   begin
            IFS_IDF_INSTR_o                       <=  IFS_IDF_INSTR_o;           
            IFS_IDF_PC_o                          <=  IFS_IDF_PC_o;              
            IFS_IDF_BUBBLE_FLAG_o                 <=  IFS_IDF_BUBBLE_FLAG_o;
            IFS_IDF_BRANCH_RESERVE_ADDR_o         <=  IFS_IDF_BRANCH_RESERVE_ADDR_o;  
            IFS_IDF_BRANCH_PREDIC_RES_o           <=  IFS_IDF_BRANCH_PREDIC_RES_o;
        end
        else                begin
            IFS_IDF_INSTR_o                       <=  IFS_IDF_INSTR_i;           
            IFS_IDF_PC_o                          <=  IFS_IDF_PC_i;              
            IFS_IDF_BUBBLE_FLAG_o                 <=  IFS_IDF_BUBBLE_FLAG_i;
            IFS_IDF_BRANCH_RESERVE_ADDR_o         <=  IFS_IDF_BRANCH_RESERVE_ADDR_i;
            IFS_IDF_BRANCH_PREDIC_RES_o           <=  IFS_IDF_BRANCH_PREDIC_RES_i;
        end
    end

endmodule